"""
@Author  : 康帅
@Time    : 2021/6/3 10:00
@Function: 机器学习
"""
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.preprocessing import MinMaxScaler, StandardScaler
import jieba
import pandas as pd


def data_sets_demo():
    """
    sklearn数据集使用
    :return:
    """
    iris = load_iris()
    # 获取数据集
    print(f'鸢尾花数据及的返回值{iris}')
    print(f'鸢尾花的特征值{iris["data"]}')
    print(f'鸢尾花的目标值{iris.target}')
    print(f'鸢尾花特征的名字{iris.feature_names}')
    print(f'鸢尾花目标值的名字{iris.target_names}')
    print(f'鸢尾花的描述{iris.DESCR}')

    # 数据集划分
    # 训练集特征值 测试集特征值 训练集目标值 测试集目标值
    # test_size 测试集的大小，一般为float
    # random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
    print(f"训练集特征值:{x_train, x_train.shape}")
    print(f"测试集特征值:{x_test, x_test.shape}")
    return None


def dict_demo():
    """
    对字典类型的数据进行特征抽取,转换成one-hot编码
    :return:
    """
    data = [{'city': '北京', 'temperature': 100},
            {'city': '上海', 'temperature': 60},
            {'city': '深圳', 'temperature': 30}]

    # 1、实例化一个转换器类 sparse=False是稀疏矩阵 默认是True
    transfer = DictVectorizer(sparse=True)
    # 2、调用fit_transform
    data_new = transfer.fit_transform(data)
    # toarray()相当于sparse=False
    print(f"返回的结果{data_new.toarray()}")
    # 打印特征名字
    print(f"特征名字：{transfer.get_feature_names()}")

    """
    加sparse变为稀疏矩阵的区别
    (0, 1)	1.0      [[  0.   1.   0. 100.]
    (0, 3)	100.0     [  1.   0.   0.  60.]
    (1, 0)	1.0       [  0.   0.   1.  30.]]
    (1, 3)	60.0
    (2, 2)	1.0
    (2, 3)	30.0  
    """


def count_demo():
    """
    对文本进行特征抽取 countvetorizer
    根据单词进程抽取
    :return:
    """
    data = ["life is short,i like like python",
            "life is too long,i dislike python"]

    transfer = CountVectorizer()

    data_new = transfer.fit_transform(data)
    print(f"文本特征抽取的结果：{data_new.toarray()}")
    print(f"特征名字:{transfer.get_feature_names()}")
    return None


def count_chinese_demo():
    """
    对中文文本进行特征抽取 countvetorizer
    根据短语进行分类
    :return:
    """
    data = ["我爱北京天安门",
            "天安门上太阳升"]

    transfer = CountVectorizer()

    data_new = transfer.fit_transform(data)
    print(f"文本特征抽取的结果：{data_new.toarray()}")
    print(f"特征名字:{transfer.get_feature_names()}")
    return None


def cut_word(text):
    """
    pip3 install jieba
    对中文进行分词
    "我爱北京天安门"————>"我 爱 北京 天安门"
    :return:
    """
    text = " ".join(list(jieba.cut(text)))
    return text


def text_chinese_count_demo2():
    """
    对中文文本进行特征抽取
    :return:
    """
    data = ["一种还是一种今天很残酷，明天更残酷，后天很美好，但绝对大部分是死在明天晚上，所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的，这样当我们看到宇宙时，我们是在看它的过去。",
            "如果只用一种方式了解某样事物，你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]

    # 将原始数据转换成分好词的形式
    text_list = []
    for sent in data:
        text_list.append(cut_word(sent))
    print(text_list)

    # 1、实例化一个转换器类 stop_words移除指定的特征词
    transfer = CountVectorizer(stop_words=["一种", "所以"])
    # 2、调用fit_transform
    data = transfer.fit_transform(text_list)
    print(f"文本特征抽取的结果：{data.toarray()}")
    print(f"返回特征名字：{transfer.get_feature_names()}")


def text_chinese_tfidf_demo():
    """
    对中文进行特征抽取 Tf-idf文本特征提取
    TF-IDF作用：用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度
    :return: None
    """
    data = ["一种还是一种今天很残酷，明天更残酷，后天很美好，但绝对大部分是死在明天晚上，所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的，这样当我们看到宇宙时，我们是在看它的过去。",
            "如果只用一种方式了解某样事物，你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    # 将原始数据转换成分好词的形式
    text_list = []
    for sent in data:
        text_list.append(cut_word(sent))
    print(text_list)

    # 1、实例化一个转换器类
    transfer = TfidfVectorizer(stop_words=['一种', '不会', '不要'])
    # 2、调用fit_transform
    data = transfer.fit_transform(text_list)
    print(f"文本特征抽取的结果：{data.toarray()}", )
    print(f"返回特征名字：{transfer.get_feature_names()}", )
    return None


def minmax_demo():
    """
    数值型数据的无量纲化
    特征预处理：归一化
    特征的单位或者大小相差较大，或者某特征的方差相比其他的特征要大出几个数量级，
    容易影响（支配）目标结果，使得一些算法无法学习到其它的特征
    :return: None
    """
    data = pd.read_csv("dating.txt")
    # 1、实例化一个转换器类 feature_range设置归一化后数据起点终点的临界值
    transfer = MinMaxScaler(feature_range=[2, 3])
    # 2、调用fit_transform
    data_new = transfer.fit_transform(data[['milage', 'Liters', 'Consumtime']])
    print(f"归一化后的数据{data_new}")


def stand_demo():
    """
    数值型数据的无量纲化
    特征预处理：标准化
    对于归一化来说：如果出现异常点，影响了最大值和最小值，那么结果显然会发生改变
    对于标准化来说：如果出现异常点，由于具有一定数据量，少量的异常点对于平均值的影响并不大，从而方差改变较小
    :return: None
    """
    data = pd.read_csv("dating.txt")
    # 1、实例化一个转换器类
    transfer = StandardScaler()
    # 2、调用fit_transform
    data_new = transfer.fit_transform(data[['milage', 'Liters', 'Consumtime']])
    print(f"标准化后的数据{data_new}")


if __name__ == '__main__':
    # data_sets_demo()
    # dict_demo()
    # count_demo()
    # count_chinese_demo()
    # text_chinese_count_demo2()
    # text_chinese_tfidf_demo()
    # minmax_demo()
    stand_demo()
